#include "bsp_delay.h"

static volatile uint32_t uwTick; // 定义计数变量，类似uwTick

/**
 * @brief  初始化定时器，1ms中断一次
 * @retval None
 */
void bsp_Delay_Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; // 总线时钟使能

    NVIC_SetPriority(TIM5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
    NVIC_EnableIRQ(TIM5_IRQn);                    // NVIC中断使能

    TIM5->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE); // 使用内部时钟
    TIM5->PSC = 99;                               // 时钟频率100M，预分频系数99
    TIM5->ARR = 999;                              // 预装载值999，1ms时基
    TIM5->CR1 &= ~TIM_CR1_DIR;                    // 向上计数
    TIM5->CR1 &= ~TIM_CR1_CKD;                    // 内部不分频
    TIM5->CR1 |= TIM_CR1_ARPE;                    // 预装载使能
    TIM5->DIER |= TIM_DIER_UIE;                   // 使能Update中断
    TIM5->SR &= ~TIM_SR_UIF;                      // 清除Update中断标志位
    TIM5->CR1 |= TIM_CR1_CEN;                     // 使能计数器
}

/**
 * @brief  获取系统时基
 * @param  None
 * @retval 实时时间
 */
uint32_t bsp_GetTick(void)
{
    return uwTick;
}

/**
 * @brief  毫秒级阻塞延时
 * @param  cnt : 延时ms数
 * @retval None
 */
void Delay_ms(uint32_t cnt)
{
    uint32_t tickStart = bsp_GetTick();
    uint32_t wait = cnt;
    while (bsp_GetTick() - tickStart < wait) {
    }
}

/**
 * @brief  微秒级阻塞延时
 * @param  cnt : 延时us数
 * @retval None
 */
void Delay_us(uint32_t cnt)
{
    // uint32_t temp = cnt + microsecond();

    // while (temp >= microsecond())
    //     ;
}

/**
 * @brief This function handles TIM5 global interrupt.
 */
void TIM5_IRQHandler(void)
{
    if (TIM5->SR & TIM_SR_UIF)   // 判断定时器是否溢出
    {
        TIM5->SR &= ~TIM_SR_UIF; // 清除更新标志位
        uwTick++;                // 计数
    }
}
